﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace IFramework
{
    public class MyThreadManager : Singleton<MyThreadManager>,IThreadManager,IObserver
    {
        public override void Dispose()
        {
            ObserveManager.Instance.RemoveObserver(this, this);
            eve = null;
            thread.Abort();
            thread = null;
            pool.Clear();
            runningPool.Clear();
            runningPool = null;
            pool = null;
        }
        public override void OnSingletonInit()
        {
            eve = new ManualResetEvent(false);
            pool = new Queue<ThreadTaskBox>();
            runningPool = new List<ThreadTaskBox>();
            ObserveManager.Instance.AddObserver(this, this);
        }
        private bool isRunning;
        private ManualResetEvent eve;
        private Thread thread;
        private Queue<ThreadTaskBox> pool;
        private List<ThreadTaskBox> runningPool;
        public void Run()
        {
            this.eve.Set();
            isRunning = true;
        }
        public void Stop()
        {
            if (pool.Count != 0) return;
            this.eve.Reset();
            isRunning = false;
        }
        public void RunTask(Action task, Action callback)
        {
            if (!isRunning)
            {
                Run();
            }
            lock (pool)
            {
                pool.Enqueue(PoolManager.Instance.GetPoolObj<ThreadTaskBox>(this,task,callback));
            }
        }
        private void RunTask()
        {
            while (true)
            {
                this.eve.WaitOne();
                lock (pool)
                {
                    runningPool.Clear();
                    runningPool.AddRange(pool);
                    pool.Clear();
                }
                MyThread th = PoolManager.Instance.GetPoolObj<MyThread>(this);
                th.RunTask(runningPool.ToArray());
                runningPool.Clear();
                lock (pool)
                {
                    if (pool.Count == 0)
                    {
                        ObserveManager.Instance.Notify(null,this, 0, this);
                    }
                }
            }
        }

        public void Listen(EventArgs args, Type eventType, int code, params object[] message)
        {
            if ((message[0] as MyThreadManager) != this) return;
            Stop();
        }

       
    }
}